package com.winning.pmph.utils;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;

/**
 * @author 刘亚飞
 * @date 2020-10-21 15:31
 */
@Slf4j
public class UploadFileUtil {

    /**
     * 上传文件, 默认放到download/temp下, 重命名并返回;
     * @param file
     * @return
     */
    public static String uploadFile(MultipartFile file) {
        return uploadFile(file, ApplicationContextUtil.BASE_DOWN_FORDER + "temp/", true);
    }

    public static String uploadFile(MultipartFile file, String savePath) {
        return uploadFile(file, savePath, true);
    }

    public static String uploadFile(MultipartFile file, @Nonnull String savePath, boolean useNewFileName) {
        if (file.isEmpty()) {
            throw new RuntimeException("上传失败，请选择文件");
        }
        File dir = new File(savePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        if (!savePath.endsWith("/")) {
            savePath += "/";
        }
        String fileName = file.getOriginalFilename();
        String storedName = fileName;
        if (useNewFileName) {
            String fileType = fileName.substring(fileName.lastIndexOf("."));
            storedName = IdWorker.getIdStr() + fileType;
        }
        File dest = new File(savePath + storedName);
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("文件上传,存储路径:" + savePath);
        return storedName;
    }

    /**
     * 字节转换为 KB, MB
     *
     * @param size
     * @return
     */
    public static String readableFileSize(long size) {
        if (size <= 0) return "0";
        final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
        int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
        return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
    }

    /**
     * 把文件从一个目录转移到另一个目录
     *
     * @param from         原位置
     * @param to           目标位置
     * @param deleteOrgDir 是否删除原位置的文件
     * @throws Exception 如果转移失败或者删除原位置文件失败
     */
    public static void transferFile(String from, String to, boolean deleteOrgDir) throws Exception {
        if (StringUtils.isBlank(from)) {
            throw new Exception("参数from的值为空");
        } else if (StringUtils.isBlank(to)) {
            throw new Exception("参数to的值为空");
        }

        File orgFile = new File(from);
        File targetFile = new File(to);

        String targetDirStr = StringUtils.removeEnd(to, orgFile.getName());
        File targetDir = new File(targetDirStr);
        if (!targetDir.exists()) {
            boolean allDirectoryWasCreated = targetDir.mkdirs();
            if (!allDirectoryWasCreated) {
                throw new Exception("未能成功创建目标文件夹");
            }
        }

        if (targetFile.exists()) {
            boolean successfullyDeleted = targetFile.delete();
            if (!successfullyDeleted) {
                throw new RuntimeException("目标目录" + targetFile.getPath()
                        + "已经存在，并且不能成功删除，文件在移动过程中可能因此失败");
            }
        }
        boolean renamingSucceeded = orgFile.renameTo(targetFile);
        if (!renamingSucceeded) {
            throw new Exception("移动文件失败");
        }

        if (deleteOrgDir) {
            if (orgFile.exists()) {
                boolean successfullyDeleted = orgFile.delete();
                if (!successfullyDeleted) {
                    throw new Exception("未能成功删除原文件");
                }
            }
        }
    }
}
